package com.tte.common.utils;

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 文件处理工具类
 * @Author: DongWH
 */
@Component
public class FileUtils {


    /**
     * 获取文件后缀名
     * @param filePath
     * @return
     */
    public static String getFileExt(String filePath){
        //获取后缀名
        return filePath.substring(filePath.lastIndexOf(".") + 1).toLowerCase();
    }

    public static String getFileExt(File file){
        //获取后缀名
        return getFileExt(file.getPath());
    }

    /**
     * 判断目录是否存在
     * @param dirPathStr 目录路径
     * @Author: DongWH
     */
    public Boolean existsDirectory(String dirPathStr){
        File file = new File(dirPathStr);
        return file.exists() && file.isDirectory();
    }

    /**
     * @Description: 判断文件是否存在
     * @param filePathStr 文件路径
     * @Author: DongWH
     */
    public Boolean existsFile(String filePathStr){
        File file = new File(filePathStr);
        return file.exists();
    }

    /**
     * 创建文件 多层文件
     * @Author: DongWH
     * @Date: 2023/5/16 16:25
     * @Param null
     * @return:
     */
    public static File createDirectoryAndFile(String filePath){
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        if (!file.exists()) {
            try {
                file.createNewFile();
                return file;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    public static File createDirectoryAndFile(String parentPath,String fileName){
        File directory = new File(parentPath);
        if (!directory.exists() || !directory.isDirectory()){
            directory.mkdirs();
        }
        String filePath = parentPath + "/" + fileName;
        File file = new File(filePath);
        if (!file.exists()) {
            try {
                file.createNewFile();
                return file;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    /**
     * 创建目录和文件
     * @Author: DongWH
     */
    public Boolean createDirectoryAndFile1(String pathStr) throws IOException {
        File file = new File(pathStr); //实例化File对象
        if(file.isDirectory()){
            if (!file.exists()) {
                file.mkdirs();
            }
        }
        if(file.getParentFile().exists()){
            return file.createNewFile();
        }else{
            file.getParentFile().mkdirs(); //创建目录
            return file.createNewFile();
        }
    }


    /**
     * 删除文件
     * @param file 文件对象
     */
    public static boolean deleteFile(File file) {
        try {
            if (!file.exists()){
                return true;
            }
            return file.delete();
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 删除文件
     * @param filePath
     */
    public static boolean deleteFile(String filePath) {
        return deleteFile(new File(filePath));
    }

    /**
     * 删除文件或删除目录下所有文件
     * @param dirFile
     * @return
     */
    public static void deleteDirectoryOrFile(File dirFile) {
        if (dirFile.isDirectory()) {
            File[] subFileList = dirFile.listFiles();
            for (int i = 0; i < subFileList.length; i++){
                deleteFile(subFileList[i]);
            }
            dirFile.delete();
        } else {
            dirFile.delete();
        }
    }

    /**
     * 向文本文件写入文本
     * @Author: DongWH
     * @Date: 2022/11/9 11:54
     * @Param txtFile 文本文件
     * @param content 文本内容
     * @return:
     */
    public static void writerToFile(File txtFile, String content) {
        try {
            FileWriter fw = new FileWriter(txtFile);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(content);
            bw.flush();
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 向文本文件写入文本
     * @Author: DongWH
     * @Date: 2022/11/9 11:54
     * @Param txtFile 文本文件
     * @param content 文本内容
     * @return:
     */
    public static void writerToBuffer(BufferedWriter bw, String content) {
        try {
            bw.write(content);
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // MultipartFile   这个对象是SpringMvc提供的文件上传的请求的类
    // 它的底层会自动和httpServletRequest request 中的request.getInputStream() 整合  从而达到文件上传的目的
    //   dir 指定上传的目录
    //  文件上传底层的原理是 request.getInputStream()
    public  String uploadImg(MultipartFile file , String dir ){

        try {
            // 截取文件名 的后缀 防止出现文件名的重复 覆盖
            String realfilename = file.getOriginalFilename();
            String imgSuffix = realfilename.substring(realfilename.lastIndexOf("."));
            //  将其生成唯一的文件名
            String newfilename = UUID.randomUUID().toString()+imgSuffix;

            //  日期目录
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath  = dateFormat.format(new Date());


            String servrepath="D:/temp";


            // 指定文件上传的目录   生成一个最终的目录
            File targetFile  = new File(servrepath+dir,datePath);
            if(!targetFile.exists()) targetFile.mkdir();

            // 指定文件上传以后服务器完整的文件名
            File targetFilname = new File(targetFile,newfilename);
            //   文件上传
            file.transferTo(targetFilname);

            String filename = dir+"/"+datePath+"/"+newfilename;

            return filename;
        } catch (IOException e) {
            e.printStackTrace();
            return "fail";
        }
    }

    /**
     * 重命名文件
     * @param oldFilePath
     * @param newFilePath
     */
    public static void fileMove(String oldFilePath,String newFilePath){
        Path oldPath = Paths.get(oldFilePath);
        Path newPath = Paths.get(newFilePath);
        try {
            Files.move(oldPath, newPath, StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 复制文件
     * @param sourcePathStr
     * @param targerPathStr
     */
    public static void copyFile(String sourcePathStr,String targerPathStr){
        try {
            Path sourcePath = Paths.get(sourcePathStr);
            Path targerPath = Paths.get(targerPathStr);
            Files.copy(sourcePath, targerPath, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("文件复制成功！");
        } catch (IOException  e) {
            System.out.println("文件复制失败: " + e.getMessage());
        }
    }

    public static String getExt(String fileName){
        int lastDotIndex = fileName.lastIndexOf(".");
        if (lastDotIndex >= 0 && lastDotIndex < fileName.length() - 1) {
            String fileExtension = fileName.substring(lastDotIndex + 1);
            return fileExtension;
        }
        return "";
    }
    public static String getFileName(String fileName){
        int position = fileName.lastIndexOf(".");
        String nameWithoutExtension = fileName.substring(0, position);
        return nameWithoutExtension;
    }


    public static void createZipFile(String folderStr,String zipFilePathStr){
        // 创建一个输出流将数据写入ZIP文件
        try (FileOutputStream fos = new FileOutputStream(zipFilePathStr);
             ZipOutputStream zos = new ZipOutputStream(fos)) {
            // 调用递归方法压缩文件或文件夹
            addToZipFile(folderStr, folderStr, zos);
            System.out.println("文件已成功打包成 " + zipFilePathStr);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void addToZipFile(String path, String sourceFile, ZipOutputStream zos) throws IOException {
        File file = new File(sourceFile);
        // 如果是文件夹，则获取其内容并递归调用此方法
        if (file.isDirectory()) {
            String[] fileList = file.list();
            if (fileList != null) {
                for (String fileName : fileList) {
                    addToZipFile(path, sourceFile + File.separator + fileName, zos);
                }
            }
            return;
        }
        // 如果是文件，则将其添加到ZIP文件中
        try (FileInputStream fis = new FileInputStream(sourceFile)) {
            String entryName = sourceFile.substring(path.length() + 1); // 获取ZIP中的条目名称
            ZipEntry zipEntry = new ZipEntry(entryName);
            zos.putNextEntry(zipEntry);

            byte[] bytes = new byte[1024];
            int length;
            while ((length = fis.read(bytes)) >= 0) {
                zos.write(bytes, 0, length);
            }
        }
    }
}